package com.demo.study.thread;

import lombok.Data;

/**
 * T02_ThreadLocal
 * ThreadLocal可以为当前线程填充一个线程变量，该变量对其他线程而言是隔离的。
 * ThreadLocal为变量在每个线程中都创建了一个副本，那么每个线程可以访问自己内部的副本变量。
 * 多个线程间，变量是不共享的，所以就不存在多线程间共享的问题
 *
 * @author Baymax
 * @since 2024-08-15
 */
public class T03_ThreadLocal {

    static int result = 0;
    //static AtomicInteger result = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        //test4();
        test5();
    }

    private static void test5() {
        Person person = new Person();
        person.setName("默认");
        person.setAge(0);

        ThreadLocal<Person> tl = new ThreadLocal<>();
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            Thread thread = new Thread(() -> {
                person.setName("姓名" + finalI);
                person.setAge(finalI);
                tl.set(person);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + "->" + person);
            });
            thread.setName("线程" + i);
            thread.start();
        }
    }

    @Data
    static class Person {
        String name;

        int age;

        @Override
        public String toString() {
            return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
        }
    }

    private static void test4() {
        Txt txt = new Txt();
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            Thread thread = new Thread(() -> {
                txt.setContext("" + finalI);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + " -> 内容" + txt.getContext());
            });
            thread.setName("线程" + i);
            thread.start();
        }
    }

    static class Txt {
        ThreadLocal<String> tl = new ThreadLocal<>();

        private String context;

        public String getContext() {
            return tl.get();
        }

        public void setContext(String context) {
            tl.set(context);
        }
    }

    private static void test1() {
        // ThreadLocal<Person> tl1 = new ThreadLocal<>();
        // Person person = new Person("张三", 20, SexEnum.M);

        int num = 1;
        ThreadLocal<Integer> tl1 = new ThreadLocal<>();
        ThreadLocal<String> tl2 = new ThreadLocal<>();

        Thread thread1 = new Thread(() -> {
            // tl1.set(person);
            // Person person1 = tl1.get();
            // person1.setAge(30);
            // System.out.println("线程1: " + person1);
            tl1.set(num);
            int curNum = tl1.get();
            curNum++;
            System.out.println("线程1: " + curNum);
        });

        Thread thread2 = new Thread(() -> {
            // tl1.set(person);
            // Person person2 = tl1.get();
            // person2.setAge(40);
            // System.out.println("线程2: " + person2);
            tl1.set(num);
            int curNum = tl1.get();
            curNum++;
            System.out.println("线程1: " + curNum);
        });

        thread1.start();
        thread2.start();
    }
}
